export class GomokuGame {
  constructor() {
    /** 棋盘大小，默认15*15 二维数组（行列） */
    this.boardSize = 15;
    this.board = Array(this.boardSize).fill().map(() => Array(this.boardSize).fill(null));

    /** 状态赋予默认值⬇️ */

    this.currentPlayer = 'black';// 当前下棋方
    this.gameOver = false; // 是否游戏结束
    this.onlineMode = false;// 游戏是否正式开始了
    this.playerColor = null;// 客户端棋手颜色
    this.isMyTurn = false;// 是否是当前客户端棋手的回合
  }

  makeMove(row, col) {
    const isOpponentMove = this.currentPlayer !== this.playerColor;
    // 游戏结束 || 该区域有棋子 || 非自身回合(对手棋豁免) 时操作无效
    if (this.gameOver || this.board[row][col] || (this.onlineMode && !(this.isMyTurn || isOpponentMove))) {
      return false;
    }

    this.board[row][col] = this.currentPlayer;// 为该区域设置棋手方颜色

    /** 获胜逻辑 */
    if (this.checkWin(row, col)) {
      this.gameOver = true;
      return { result: 'win', player: this.currentPlayer };
    }
    // 当前棋手下完后该反色棋手下棋，反转下棋权
    this.currentPlayer = this.currentPlayer === 'black' ? 'white' : 'black';
    if (this.onlineMode) {
      this.isMyTurn = false;
    }
    return { result: 'continue' };
  }

  // 检查是否获胜
  checkWin(row, col) {
    // 根据当前落子位置，判断其四个方向上有无五子连珠
    const directions = [
      [[0, 1], [0, -1]],// 右、左（水平）  方向
      [[1, 0], [-1, 0]],// 下、上（竖直） 方向
      [[1, 1], [-1, -1]],// 东南、西北（斜线） 方向
      [[1, -1], [-1, 1]]// 西南、东北（斜线） 方向
    ];

    return directions.some(dir => {
      // 算上自身统计连珠数量，任意方向五子连珠即获胜（some函数会在返回第一个true后不再往下执行）
      const count = 1 +
        this.countDirection(row, col, dir[0][0], dir[0][1]) +
        this.countDirection(row, col, dir[1][0], dir[1][1]);
      // 因为每个方向分两半统计，所以会出现大于5的情况
      return count >= 5;
    });
  }

  /** 统计当前方向（半截方向）连珠数量 */
  countDirection(row, col, deltaRow, deltaCol) {
    const player = this.board[row][col]; // 当前落子方颜色
    let count = 0;
    let currentRow = row + deltaRow;
    let currentCol = col + deltaCol;

    while (
      // 不超出边界检测
      currentRow >= 0 &&
      currentRow < this.boardSize &&
      currentCol >= 0 &&
      currentCol < this.boardSize &&
      // 延续方向上遇到同色棋子，继续执行，反之中断
      this.board[currentRow][currentCol] === player
    ) {
      // 同色棋数量加一，继续对该方向寻找
      count++;
      /**
       * directions的数据也是为了作用于以下两段代码来设计的
       */
      currentRow += deltaRow;
      currentCol += deltaCol;
    }

    return count;
  }

  reset() {
    this.board = Array(this.boardSize).fill().map(() => Array(this.boardSize).fill(null));
    this.currentPlayer = 'black';
    this.gameOver = false;
    this.isMyTurn = this.playerColor === 'black';
  }

  setOnlineMode(color) {
    this.onlineMode = true;
    this.playerColor = color;
    this.isMyTurn = color === 'black';
  }
}